var MapsViewElementID = "mapContainer";
var InfoTextElementID = "informationText";
var InfoNoteElementID = "informationNote";
var InfoContainerElementID = "infoContainer";
var DefaultLatitude = 52.531;
var DefaultLongitude = 13.385;

// Change the following constant value to setStaticMap if you want to use
// a static map instead of the pannable map.
var mapFunction;
//var mapFunction = setStaticMap;

// Use Nokia or Bing Map 
var USE_NOKIA_MAP = true;

var watchId;

// Position options for Geolocation API
var positionOptions = {
    enableHighAccuracy: false, // Low accuracy is sufficient by default
    timeout: 30000, // 30 seconds
    maximumAge: 0 // Don't accept cached location
    }

// For pannable map
var map;
var marker;
var lastPosition = [ DefaultLatitude, DefaultLongitude ];

/**
 * Initialize map and position
 */
function init()
{   
    // Use Nokia or Bing Maps
    if (USE_NOKIA_MAP) {
        mapFunction = setPannableNokiaMap;
        loadPannableNokiaMap();
    } else {
        mapFunction = setPannableBingMap;
        loadPannableBingMap();
    }
    
    // Get HTML5 Geolocation
    getPosition(mapFunction);
}

/**
 * Shows Windows Phone infomessage to user.
 */
function showMessage(msg)
{
window.external.notify(msg);
}

/**
 * Shows HTML info text.
 */
function setInformationText(text)
{
var informationTextElement = document.getElementById("informationText");
informationTextElement.innerHTML = text;
}

/**
 * Sets the information text in the HTML context.
 *
 * @param text The text to set.
 */
function setInformationText(text)
{
    var informationNoteElement = document.getElementById(InfoNoteElementID);
    informationNoteElement.style.display='block';

    var informationTextElement = document.getElementById(InfoTextElementID);
    informationTextElement.innerHTML = text;
}

/**
 * Timer for hiding info text
 */
function hideInformationText()
{
    var timer = setTimeout("doHideInformationText()",3000);
}

/**
 * Hide info text
 */
function doHideInformationText()
{
    var informationNoteElement = document.getElementById(InfoNoteElementID);
    informationNoteElement.style.display='none';
}

/**
 * Show info
 */
function showInfo()
{
    var informationContainerElement = document.getElementById(InfoContainerElementID);
    informationContainerElement.style.display='block';
}

/**
 * Close info
 */
function closeInfo()
{
    var informationContainerElement = document.getElementById(InfoContainerElementID);
    informationContainerElement.style.display='none';
}

/*
 * Is info view visible
 */
function isInfoVisible()
{
    var informationContainerElement = document.getElementById(InfoContainerElementID);
    if (isVisible(informationContainerElement))
        return '1';
    else
        return '0';
}

/*
 * Is element visible
 */
function isVisible(elem) {
  var cmpstyle = window.getComputedStyle(elem,null);
  if (parseFloat(cmpstyle.opacity) > 0 &&
      cmpstyle.visibility != 'hidden' &&
      cmpstyle.display != 'none') {
    return true;
  }
  return false;
}


/**
 * Tries to get the current position of the user using the Geolocation API.
 *
 * @param setMapFunction The function used for setting the map.
 */
function getPosition(mapFunctionParameter)
{
    if (navigator && navigator.geolocation) {
        setInformationText("Retrieving location...");
        navigator.geolocation.getCurrentPosition(mapFunctionParameter,
                                                 onError,
                                                 positionOptions);

    }
    else {
        alert("No Geolocation API available!");
    }
}


/**
 * Loads the map according to the given position.
 *
 * @param position The position received from the Geolocation API.
 */
function setStaticMap(position)
{
    hideInformationText();

    // Get the maps view element.
    var mapsViewElement = document.getElementById(MapsViewElementID);

    // Load the map and set it as the background image of the maps view
    // element.
    var url = new StaticMap({
        center: { lat: position.coords.latitude,
                  lon: position.coords.longitude },
        zoom: 12,
        size: { width: document.width, height: document.height }
    }).getCSSUrl();

    mapsViewElement.style.backgroundImage = url;
}


/**
 * Creates a pannable map.
 * Nokia Map
 */
function loadPannableNokiaMap()
{
    setInformationText("Loading Nokia Maps...");

    map = new nokia.maps.map.Display(
        document.getElementById(MapsViewElementID), {
            components: [ new nokia.maps.map.component.Behavior()],
            'zoomLevel': 12, // Zoom level for the map
            'center': [DefaultLatitude, DefaultLongitude] // Center coordinates
        }
    );
    
    
}

/**
 * Creates a pannable map.
 * Bing Map
 */
function loadPannableBingMap()
{
    setInformationText("Loading Bing Maps...");
    
    map = new Microsoft.Maps.Map(document.getElementById(MapsViewElementID), 
        {credentials: 'AtqCp27rVpTHmmf0iQjxS36z1YdD1RnucNIFt0g4Yz529GW3AuybYVBGb55EuMZi',
        mapTypeId: Microsoft.Maps.MapTypeId.road,
        showScalebar: false,
        disableZooming: true,
		center: new Microsoft.Maps.Location(DefaultLatitude, DefaultLongitude),
        enableClickableLogo: false,
        enableSearchLogo: false,
        showDashboard: false,
        zoom: 12});
}


/**
 * Centers the map on the given position and add a marker.
 * Nokia Maps
 *
 * @param position The position received from the Geolocation API.
 */
function setPannableNokiaMap(position)
{
    hideInformationText(); 
    
    // Store the position.
    lastPosition = position.coords;

    // Center the map.
    map.setCenter( [ position.coords.latitude, position.coords.longitude ] );

    // Create and add the marker.
    marker = new nokia.maps.map.Marker(
                [position.coords.latitude, position.coords.longitude],
                {
                    text: "Me",
                    draggable: false
                });

    // Uncomment the following to use a custom marker.
    //marker.set("icon", "images/marker.png");

    map.objects.clear();
    
    map.objects.add(marker);
}

/**
 * Centers the map on the given position and add a marker.
 * Bing Maps
 *
 * @param position The position received from the Geolocation API.
 */
function setPannableBingMap(position)
{
    hideInformationText(); 
    
    // Store the position.
    lastPosition = position.coords;

    //showMessage(position.coords.latitude + " " + position.coords.longitude);
    
    // Map center pos
    var location = new Microsoft.Maps.Location(position.coords.latitude,position.coords.longitude);
    map.setView({ zoom: 12, center: location });
    
    // Marker
    var pin = new Microsoft.Maps.Pushpin(location);
    map.entities.clear();
    map.entities.push(pin); 

    // Request repeated updates
    //watchId = navigator.geolocation.watchPosition(mapFunction,
    //                                             onError,
    //                                             positionOptions);
    
}



/**
 * Callback for handling errors. Displays the error message in the HTML
 * context.
 *
 * @param error The occured error.
 */
function onError(error)
{
    var message = "Geolocation API error";
    hideInformationText();

    switch (error.code) {
      case error.PERMISSION_DENIED:
          message = "Enable device location and try again.";
          break;
       case error.POSITION_UNAVAILABLE:
          message = "The current position could not be determined.";
          break;
       case error.PERMISSION_DENIED_TIMEOUT:
          message = "The current position could not be determined " +
                    "within the specified timeout period.";
          break;
    }

    showMessage(message);
}


/**
 * Sets the accuracy according to the given argument. Tries to update the
 * position automatically.
 *
 * @param accuracy Should be "high" or "low" depending on the desired accuracy.
 */
function setAccuracy(accuracy)
{
    if (accuracy == "high") {
        setInformationText("Accuracy set: high");
        positionOptions.enableHighAccuracy = false;
    }
    else {
        setInformationText("Accuracy set: low");
        positionOptions.enableHighAccuracy = true;
    }

    getPosition(mapFunction);
}


/**
 * Centers the map. This has an effect only if the pannable map is in use.
 */
function centerMap()
{
    if (map) {
        map.setCenter(lastPosition);
    }
}


/**
 * Updates the position.
 */
function update()
{
    setInformationText("Update...");
    getPosition(mapFunction);
}

